package com.morningstar.flow.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.collection.CollUtil;
import com.morningstar.common.result.Result;
import com.morningstar.flow.controller.result.FlowGraph;
import com.morningstar.flow.dao.entity.FlowInstanceTimeLine;
import com.morningstar.flow.dao.entity.FlowNode;
import com.morningstar.flow.service.FlowInstanceTimeLineService;
import com.morningstar.flow.service.FlowNodeService;
import com.morningstar.system.api.feign.ISystemUserFeign;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/flow/instance/timeline")
public class FlowInstanceTimeLineController {

    @Resource
    private FlowInstanceTimeLineService flowInstanceTimeLineService;

    @Resource
    private FlowNodeService flowNodeService;

    @Resource
    private ISystemUserFeign systemUserFeign;

    @Resource
    private TaskService taskService;

    /**
     * 获取审批记录
     *
     * @param instanceId 流程实例Id
     * @return 流程列表
     */
    @GetMapping("/{instanceId}")
    @SaCheckLogin
    public Result<Object> history(@PathVariable("instanceId") String instanceId) {
        List<FlowInstanceTimeLine> list = flowInstanceTimeLineService.getByProcessInstanceId(instanceId);
        List<String> taskDefId = list
                .stream()
                .map(FlowInstanceTimeLine::getNodeActivityId)
                .filter(StringUtils::isNotBlank)
                .toList();
        Map<String, String> nodeNameMap = new HashMap<>();
        if (CollUtil.isNotEmpty(taskDefId)) {
            nodeNameMap = flowNodeService
                    .lambdaQuery()
                    .in(FlowNode::getNodeActivityId, taskDefId)
                    .list()
                    .stream()
                    .collect(Collectors.toMap(FlowNode::getNodeActivityId, FlowNode::getNodeName));
        }
        Map<Long, String> userNameMap = systemUserFeign.selectUserIdAndName();
        Map<String, String> finalNodeNameMap = nodeNameMap;
        list.forEach(item -> {
            item.setUserName(userNameMap.get(item.getUserId()));
            item.setNodeName(finalNodeNameMap.get(item.getNodeActivityId()));
        });
        return Result.successData(list);
    }

    /**
     * 获取流程节点图
     *
     * @param instanceId 流程实例Id
     * @return 流程列表
     */
    @GetMapping("/flowGraph/{instanceId}")
    public Result<Object> flowGraph(@PathVariable("instanceId") String instanceId) {
        List<String> agreeIds = new ArrayList<>();
        List<String> rejectIds = new ArrayList<>();
        List<String> ingIds = taskService.createTaskQuery()
                .processInstanceId(instanceId)
                .list()
                .stream()
                .map(Task::getTaskDefinitionKey)
                .toList();
        Map<String, List<FlowInstanceTimeLine>> historyMap = flowInstanceTimeLineService
                .getByProcessInstanceId(instanceId)
                .stream()
                .filter(item -> StringUtils.isNotBlank(item.getNodeActivityId()))
                .filter(item -> !ingIds.contains(item.getNodeActivityId()))
                .collect(Collectors.groupingBy(FlowInstanceTimeLine::getNodeActivityId));
        if (CollUtil.isEmpty(historyMap.keySet())) {
            return Result.successData(new FlowGraph(agreeIds, rejectIds, ingIds));
        }
        for (String key : historyMap.keySet()) {
            List<FlowInstanceTimeLine> list = historyMap.get(key);
            if (CollUtil.isEmpty(list)) {
                continue;
            }
            List<FlowInstanceTimeLine> sortedList = list.stream()
                    .sorted(Comparator.comparing(FlowInstanceTimeLine::getOperateTime, Comparator.reverseOrder()))
                    .toList();
            // 获取最新 审批记录
            FlowInstanceTimeLine flowInstanceTimeLine = sortedList.get(0);
            if (StringUtils.equalsIgnoreCase(flowInstanceTimeLine.getType(), "审批拒绝")) {
                rejectIds.add(flowInstanceTimeLine.getNodeActivityId());
            } else {
                agreeIds.add(flowInstanceTimeLine.getNodeActivityId());
            }
        }
        return Result.successData(new FlowGraph(agreeIds, rejectIds, ingIds));
    }

}
